package com.ajnp.springcloud.controller;


import com.ajnp.springcloud.lb.LoadBalancer;
import com.ajnp.springcloud.lb.MyLB;
import entities.CommonResult;
import entities.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("/consumer")
public class OrderController {
    //模拟客户端请求服务


    //静态的设置请求服务路径  在单机版使用时 可以指定请求路径 但使用服务集群后将不可用
    //private static final String PAYMENT_URL="http://localhost:8001/payment/";
    //集群通过服务的名称进行分配请求 实现负载均衡
    private static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE/payment/";
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private LoadBalancer loadBalancer;

    @Autowired
    private DiscoveryClient discoveryClient;

    //请求添加操作
    @PostMapping("/payment/create")
    public CommonResult<Payment> create(Payment payment) {
        //读操作使用get 写操作使用post..()
        //postForObject需要三个参数
        //参数一：url:  调用地址路径
        //参数二： 请求参数
        //参数三： 返回的参数类型
        log.info(payment.getSerial());
        return restTemplate.postForObject(PAYMENT_URL + "getcreate", payment, CommonResult.class);
    }
    //getForObject  返回对象为响应体中的数据转化成对象 ，基本上可以理解为json

    @GetMapping("/payment/get/{id}")       //restful 风格的请求也需要 使用restful风格进行请求
    public CommonResult<Payment> get(@PathVariable("id") Long id) {
        //进行读取操作时 使用get方式
        return restTemplate.getForObject(PAYMENT_URL + "getpaymentById/" + id, CommonResult.class);
    }

//    @GetMapping("/payment/discovery")
//    public CommonResult<Object> discovery(String servername){
//        return restTemplate.postForObject(PAYMENT_URL+"discovery",servername,CommonResult.class);
//    }
//    //CLOUD-PAYMENT-SERVICE

    //getForEntity  返回对象为ResponseEntity对象，包含了响应中的一些重要信息,比如响应头, 响应状态码 ，响应体等信息
    @GetMapping("/payment/getForEntity/{id}")
    public CommonResult<Payment> get2(@PathVariable("id") Long id) {
        ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENT_URL + "getpaymentById/" + id, CommonResult.class);
        //getStatusCode()  方法中又很多2xx ,3xx,4xx 等方法 其实是 html执行方法返回的状态码 200 ，302，404 等状态码
        //判断返回的状态码是否为200
        if (entity.getStatusCode().is2xxSuccessful()) {
            log.info(entity.getBody().getMessage());
            return entity.getBody();
        } else {
            return new CommonResult(444, "操作失败");
        }
    }


    //postForEntity  返回对象为ResponseEntity对象，包含了响应中的一些重要信息,比如响应头, 响应状态码 ，响应体等信息
    @PostMapping("/payment/postForEntity")
    public CommonResult<Payment> create2(Payment payment) {

        ResponseEntity<CommonResult> forEntity = restTemplate.postForEntity(PAYMENT_URL + "getcreate", payment, CommonResult.class);

        if (forEntity.getStatusCode().is2xxSuccessful()) {
            log.info(String.valueOf(forEntity.getHeaders().getDate()));
            return forEntity.getBody();
        } else {
            return new CommonResult<>(444, "操作失败");
        }
    }

    @GetMapping("/payment/lb")
    public String getPaymentLB() {  //http://localhost/consumer/payment/lb

        //获取指定的集群的所有服务
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        // 判断指定集群是否为空
        if (instances == null || instances.size() == 0) {
            return null;
        }
        //传入所有正常运行的所有服务
        ServiceInstance serviceInstance = loadBalancer.instances(instances);
        // 获取到返回的服务路径
        URI uri = serviceInstance.getUri();

        //使用restTemplate进行连接 需要注释到 @LoadBalanced 否则无法访问到uri
        return restTemplate.getForObject(uri + "/payment/lb", String.class);
    }

    //链路监控
    @GetMapping("/payment/getzipkin")
    public String getzipkin() {
        return restTemplate.getForObject(PAYMENT_URL + "getzipkin", String.class);
    }


}
